package org.totoro.api;

import lombok.extern.slf4j.Slf4j;
import org.objectweb.asm.*;

/**
 * 方法观察
 *
 * @author daocr
 * @date 2020/9/23
 */
@Slf4j
public class MethodVisitorTest extends MethodVisitor {

    public MethodVisitorTest(int api) {
        super(api);
    }

    @Override
    public void visitParameter(String name, int access) {
        super.visitParameter(name, access);
        log.info("name：{}\taccess：{}", name, access);
    }

    @Override
    public AnnotationVisitor visitAnnotationDefault() {
        return super.visitAnnotationDefault();
    }

    @Override
    public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
        log.info("descriptor：{}\tvisible：{}", descriptor, visible);
        return super.visitAnnotation(descriptor, visible);
    }

    @Override
    public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        log.info("typeRef：{}\ttypePath：{}\tdescriptor：{}\tvisible：{}", typeRef, typePath, descriptor, visible);
        return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
    }

    @Override
    public void visitAnnotableParameterCount(int parameterCount, boolean visible) {
        log.info("parameterCount：{}\tvisible：{}", parameterCount, visible);
        super.visitAnnotableParameterCount(parameterCount, visible);
    }

    @Override
    public AnnotationVisitor visitParameterAnnotation(int parameter, String descriptor, boolean visible) {
        log.info("parameter：{}\tdescriptor：{}\tvisible：{}", parameter, descriptor, visible);
        return super.visitParameterAnnotation(parameter, descriptor, visible);
    }

    @Override
    public void visitAttribute(Attribute attribute) {
        log.info("attribute：{}", attribute);
        super.visitAttribute(attribute);
    }

    @Override
    public void visitCode() {
        super.visitCode();
    }

    @Override
    public void visitFrame(int type, int numLocal, Object[] local, int numStack, Object[] stack) {
        log.info("type：{}\tnumLocal：{}\tlocal：{}\tnumStack：{},\tstack：{}", type, numLocal, local, numStack, stack);
        super.visitFrame(type, numLocal, local, numStack, stack);
    }

    @Override
    public void visitInsn(int opcode) {
        log.info("opcode：{}", opcode);
        super.visitInsn(opcode);
    }

    @Override
    public void visitIntInsn(int opcode, int operand) {
        log.info("opcode：{}\toperand：{}", opcode, operand);
        super.visitIntInsn(opcode, operand);
    }

    @Override
    public void visitVarInsn(int opcode, int var) {
        log.info("opcode：{}\tvar：{}", opcode, var);
        super.visitVarInsn(opcode, var);
    }

    @Override
    public void visitTypeInsn(int opcode, String type) {
        log.info("opcode：{}\ttype：{}", opcode, type);
        super.visitTypeInsn(opcode, type);
    }

    @Override
    public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
        log.info("opcode：{}\towner：{}\tname：{}\tdescriptor：{}", opcode, owner, name, descriptor);
        super.visitFieldInsn(opcode, owner, name, descriptor);
    }


    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
        log.info("opcode：{}\towner：{}\tname：{}\tdescriptor：{}\tisInterface：{}", opcode, owner, name, descriptor, isInterface);
        super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
    }

    @Override
    public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
        log.info("name：{}\tdescriptor：{}\tbootstrapMethodHandle：{}\tbootstrapMethodArguments：{}", name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
        super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
    }

    @Override
    public void visitJumpInsn(int opcode, Label label) {
        log.info("opcode：{}\tlabel：{}", opcode, label);
        super.visitJumpInsn(opcode, label);
    }

    @Override
    public void visitLabel(Label label) {
        log.info("label：{}", label);
        super.visitLabel(label);
    }

    @Override
    public void visitLdcInsn(Object value) {
        log.info("value：{}", value);
        super.visitLdcInsn(value);
    }

    @Override
    public void visitIincInsn(int var, int increment) {
        log.info("var：{}\tincrement：{}", var, increment);
        super.visitIincInsn(var, increment);
    }

    @Override
    public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
        log.info("min：{}\tmax：{}\tdflt：{}\tlabels：{}", min, max, dflt, labels);
        super.visitTableSwitchInsn(min, max, dflt, labels);
    }

    @Override
    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
        log.info("dflt：{}\tkeys：{}\tlabels：{}", dflt, keys, labels);
        super.visitLookupSwitchInsn(dflt, keys, labels);
    }

    @Override
    public void visitMultiANewArrayInsn(String descriptor, int numDimensions) {
        log.info("descriptor：{}\tnumDimensions：{}", descriptor, numDimensions);
        super.visitMultiANewArrayInsn(descriptor, numDimensions);
    }

    @Override
    public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        log.info("typeRef：{}\ttypePath：{}\tdescriptor：{}\tvisible：{}", typeRef, typePath, descriptor, visible);
        return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
    }

    @Override
    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
        log.info("start：{}\tend：{}\thandler：{}\ttype：{}", start, end, handler, type);
        super.visitTryCatchBlock(start, end, handler, type);
    }

    @Override
    public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
        log.info("typeRef：{}\ttypePath：{}\tdescriptor：{}\tvisible：{}", typeRef, typePath, descriptor, visible);
        return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
    }

    @Override
    public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
        log.info("name：{}\tdescriptor：{}\tsignature：{}\tstart：{}\tend：{}\tindex：{}", name, descriptor, signature, start, end, index);
        super.visitLocalVariable(name, descriptor, signature, start, end, index);
    }

    @Override
    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String descriptor, boolean visible) {
        log.info("name：{}\ttypePath：{}\tstart：{}\tend：{} \tindex：{}\tdescriptor：{}\tvisible：{}", typeRef, typePath, start, end, index, descriptor, visible);
        return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
    }

    @Override
    public void visitLineNumber(int line, Label start) {
        log.info("line：{}\tstart：{}", line, start);
        super.visitLineNumber(line, start);
    }

    @Override
    public void visitMaxs(int maxStack, int maxLocals) {
        log.info("maxStack：{}\tmaxLocals：{}", maxStack, maxLocals);
        super.visitMaxs(maxStack, maxLocals);
    }
}
